import { ZRenderComp } from '../../../common/component/zrComp';
import { KeyFrameSequence } from '../../../common/animation/keyFrame';
import { hold } from '../../../common/animation/index';

import layout from './layout4';
import events from './events';

import { TitleFrame } from '../x/titleFrame';
import { TimerPanel } from './timerPanel';
import { Gear, Sign } from './gear';
import { Cables } from './cable';
import { NameTag } from './nameTag';
import { Tip } from './tips';

class Desk extends ZRenderComp {
	constructor(args) {
		super(args.parent, args.zrender);

		const l = layout.desk;
		this.createNewZRenderInstance(l.x, l.y, l.width, l.height, 'desk');

		this.titleFrame = new TitleFrameV4({ parent : this, zr : this.zr, zrender : this.zrender });
		this.timerPanel = new TimerPanel({ parent : this });
		this.gear = new Gear({ parent : this });
		this.sign = new Sign({ parent : this });
		this.tip = new Tip({ parent : this });

		this.cables = new Cables({ parent : this });
		this.nameTags = layout.nameTags.map(l =>
			new NameTag({ parent : this, ...l })
		);
		this.descFrame = new DescFrame({ parent : this });
	}
}

/**
 * zlevel=18, 19
 */
class TitleFrameV4 extends TitleFrame {
	constructor(args) {
		super({
			...args,
			colors : layout.colors,
			...layout.titleFrame,
			zlevel : 18, zlevelStatic : 19,
			titleEventName : events.TITLE_UPDATED,
		});
		this.title = this.root.scoreBoard.title;

		this.on(events.TIMER_START, this.onTimerStart.bind(this));
	}

	onTimerStart() {
		if (this.anim != null) {
			this.anim.forceToEnd();
		}
		const anim = this.anim = new KeyFrameSequence(1);
		anim.whenUpdated(this.onTextOpacityUpdate.bind(this))
			.update()
			.when(0, 1)
			.when(500, 0)
			.when(3500, 0).easing(hold)
			.when(4000, 1).callback(() => this.anim = null)
			.commit();
		this.animLastTime = Date.now();
	}

	onTextOpacityUpdate(param) {
		this.spTitle.attr({ style : { opacity : param.value }});
	}

	tick(now) {
		super.tick(now);
		if (this.anim) {
			this.anim.tick(now - this.animLastTime);
			this.animLastTime = now;
		}
	}
}

/**
 * 备注栏, 界面下半部分的框. 含以下内容:
 * 
 * 上边框, 下边框, 底面
 * zlevel=20
 */
class DescFrame extends ZRenderComp {
	constructor(args) {
		super(args.parent);

		const lw = layout.descFrame;
		this.useParentZRenderInstance(lw.x, lw.y);
		this.width = lw.width;
		this.height = lw.height;
	}

	init() {
		const w = this.width;
		const h = this.height;
		const o = 10; // offset
		const l = 2; // line width

		// 上边框的 Path2D
		const topBoundPath =
			// 上表面横线
			`M0 ${o}l${o} -${o}H${w*0.4}l${o-l} ${o-l}H${w*0.7}l${o-l} -${o-l}H${w-o}L${w} ${o}`
			+ `h-${3*l}l${l-o} ${l-o}H${w*0.7+o+l}l${l-o} ${o-l}H${w*0.4+o-3*l}l${l-o} ${l-o}H${o+2*l}L${3*l} ${o}z`
			// 小图形
			+ `M${o+4*l} ${o-2*l}h${0.04*w}l-${2*l} ${2*l}h-${0.04*w}z`
			+ `M${o+7*l+0.04*w} ${o-2*l}h${3*l}l-${2*l} ${2*l}h-${3*l}z`
			+ `M${o+13*l+0.04*w} ${o-2*l}h${3*l}l-${2*l} ${2*l}h-${3*l}z`;

		const bottomBoundPath =
			// 下表面横线
			`M10 ${h-o-5}l${o+5} ${o+5}H${0.3*w}l${o-l} ${l-o}H${0.75*w}l${o-l} ${o-l}H${w-15-o}l${o+5} -${o+5}`
			+ `h-${3*l}l${l-o-5} ${o-l+5}H${0.75*w+l+o}l${l-o} ${l-o}H${0.3*w+o-3*l}l${l-o} ${o-l}H${15+o+2*l}l${l-o-5} ${l-o-5}z`
			// 小图形
			+ `M${w-15-o-3*l} ${h-3*l}h-${3*l}l${4*l} -${4*l}h${3*l}z`
			+ `M${w-15-o-8*l} ${h-3*l}h-${4*l}l${2*l} -${2*l}h${4*l}z`
			+ `M${w-15-o-14*l} ${h-3*l}h-${4*l}l${2*l} -${2*l}h${4*l}z`
			+ `M${w-15-o-20*l} ${h-3*l}h-${3*l}l${3*l} -${3*l}h${3*l}z`;

		const backPath =
			// 底面
			`M0 ${o}l${o} -${o}H${w*0.4}l${o-l} ${o-l}H${w*0.7}l${o-l} -${o-l}H${w-o}L${w} ${o}`
			+ `V${h-15-o}L${w-15-o} ${h}H${0.75*w+o-l}l${l-o} ${l-o}H${0.3*w+o-l}l${l-o} ${o-l}H${15+o}L0 ${h-15-o}z`;

		this.createPathFromString(topBoundPath)
			.fill(layout.colors.strokeBgL2)
			.z(20, 20)
			.build();
		this.createPathFromString(bottomBoundPath)
			.fill(layout.colors.strokeBgL2)
			.z(20, 20)
			.build();
		this.createPathFromString(backPath)
			.fillLinearGradient(0, 0, 0, 1, [
				{offset:0.04, color: layout.colors.strokeBgD2},
				{offset:0.12, color: layout.colors.strokeBg},
				{offset:0.65, color: layout.colors.strokeBgL1},
				{offset:0.86, color: layout.colors.strokeBg},
				{offset:0.94, color: layout.colors.strokeBgD1},
			])
			.opacity(0.7)
			.z(20, 0)
			.build();
		this.createPathFromString(backPath)
			.fill('transparent')
			.stroke(layout.colors.strokeBgL1, 2)
			.shadow(layout.colors.strokeBgL2, 10)
			.z(20, 10)
			.build();
	}
}

export {
	Desk
};
